package com.fkframe.codegener.ui.view;

import heip.generator.entity.ColumnClazz;
import heip.generator.entity.PropEditor;
import heip.generator.entity.PropEditor.EditType;
import heip.generator.entity.TableClazz;
import heip.generator.entity.ValidateRule;
import heip.generator.entity.ValidateRule.ValidateType;
import heip.generator.main.SingleTableGenerator2;

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumn;

import cn.org.rapid_framework.generator.GeneratorProperties;

import com.fkframe.codegener.ui.EETSoftFrame;

/**
 * 单表生成机制
 * 
 * @author AGUU
 * 
 */
public class SubTableGenerView extends JPanel implements ActionListener {
	private JTextField txtModule;
	private JTextField txtTable;

	private EETSoftFrame parentFrame;

	private JButton btnLoad;
	private JButton btnGener;
	private JPanel panel;
	private JPanel mainPanel;
	private JViewport jViewport;
	private JTable table;
	JScrollPane scrollPane;
	
	private SingleTableModel tableModel = new SingleTableModel();
	
	/*Vector<String> vcol = new Vector<String>();
	{
		vcol.addElement("序号");
		vcol.addElement("字段名");
		vcol.addElement("字段中文名");
		vcol.addElement("是否查询项目");
		vcol.addElement("是否列表项目");
		vcol.addElement("是否编辑项目");
		vcol.addElement("是否编辑hidden");	
		
		vcol.addElement("校验必输");
		vcol.addElement("校验字符串长度（min,max）");
		//vcol.addElement("校验整数（min,max）");
		//vcol.addElement("校验小数（整数位数,小数位数）");
	}*/
	
	public SubTableGenerView(EETSoftFrame parent, JPanel mainPanel,JViewport jViewport) {
		this.parentFrame = parent;
		this.mainPanel = mainPanel;
		this.jViewport = jViewport;
		setLayout(new GridLayout(0, 1, 0, 0));

		JPanel panel_2 = new JPanel();
		add(panel_2);

		JLabel lblNewLabel_1 = new JLabel("模块名");
		panel_2.add(lblNewLabel_1);

		txtModule = new JTextField();
		panel_2.add(txtModule);
		txtModule.setColumns(10);

		JLabel lblNewLabel = new JLabel("表名");
		panel_2.add(lblNewLabel);

		txtTable = new JTextField();
		panel_2.add(txtTable);
		txtTable.setColumns(10);

		JButton btnNewButton = new JButton("加载");
		panel_2.add(btnNewButton);
		btnNewButton.addActionListener(this);

		btnLoad = new JButton("生成");
		panel_2.add(btnLoad);
		btnLoad.addActionListener(this);
		panel = new JPanel();

		// 声明表格模型
		LinkedHashMap<String,String> columnMap = new LinkedHashMap<String, String>();
		columnMap.put("seq", "序号");
		columnMap.put("name","属性");
		columnMap.put("cnName", "显示名");
		
		columnMap.put("isQuery", "是否查询");
		columnMap.put("isTable", "列表显示");
		columnMap.put("isEdit", "是否编辑");
		
		columnMap.put("editType", "编辑类型");
		//columnMap.put("editRule", "规则");
		
		columnMap.put("validateType1", "校验类型1");
		columnMap.put("validateRule1", "校验规则1");
		columnMap.put("validateType2", "校验类型2");
		columnMap.put("validateRule2", "校验规则2");
		//columnMap.put("validateType3", "校验类型3");
		//columnMap.put("validateRule3", "校验规则3");
		
		tableModel.setColumnMap(columnMap);
		
		table = new JTable(tableModel);
		table.setAutoscrolls(true);
		table.setFocusable(false);
		table.setColumnSelectionAllowed(false);
		table.setRowHeight(30);
		table.setAutoResizeMode(0);
		
		SingleTableModel model = (SingleTableModel) table.getModel();
		TableColumn sportColumn = this.table.getColumn(model.getColumnNameByKey("validateType1"));
		TableColumn sportColumn2 = this.table.getColumn(model.getColumnNameByKey("validateType2"));
		//TableColumn sportColumn3 = this.table.getColumn(model.getColumnNameByKey("validateType3"));
		setUpSportColumn(sportColumn);
		setUpSportColumn(sportColumn2);
		
		TableColumn sportColumn3 = this.table.getColumn(model.getColumnNameByKey("editType"));
		setEditTypeColumn(sportColumn3);
		
		/*
		 * for(int i=3;i<vcol.size();i++){ TableColumn aColumn =
		 * table.getColumnModel().getColumn(i);
		 * aColumn.setCellEditor(table.getDefaultEditor(Boolean.class));
		 * aColumn.setCellRenderer(table.getDefaultRenderer(Boolean.class)); }
		 */

		scrollPane = new JScrollPane();

		scrollPane.setViewportView(table);
		scrollPane.setSize(600, 400);
		add(scrollPane);

	}
	private TableClazz tableClazz ;
	
	public void setEditTypeColumn(TableColumn column){
		JComboBox comboBox = new JComboBox();
		
		comboBox.addItem("");
		for(EditType type : EditType.values()){
			comboBox.addItem(type.getName());
		}
		
		column.setCellEditor(new DefaultCellEditor(comboBox));

		// Set up tool tips for the sport cells.
		DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
		//renderer.setToolTipText("Click for combo box");
		column.setCellRenderer(renderer);
	}
	
	public void setUpSportColumn(TableColumn sportColumn) {
		
		//SingleTableModel model = (SingleTableModel) table.getModel();
		//TableColumn sportColumn = this.table.getColumn(model.getColumnNameByKey("validateType1"));
		
		JComboBox comboBox = new JComboBox();
		
		comboBox.addItem("");
		for(ValidateType type : ValidateType.values()){
			comboBox.addItem(type.getName());
		}
		
		sportColumn.setCellEditor(new DefaultCellEditor(comboBox));

		// Set up tool tips for the sport cells.
		DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
		//renderer.setToolTipText("Click for combo box");
		sportColumn.setCellRenderer(renderer);

	}
	
	public void reloadColumnPanel2() {
		// 刷新数据代码
		// 定义Vector 类型变量tmprow，colVec，并且赋值，就象上面那样，这里不重复了
		SingleTableModel  model= (SingleTableModel) table.getModel();

		String tableName = txtTable.getText();
		tableClazz = new TableClazz(tableName);
		int columnSize = tableClazz.getColumns().size();

		List<Map<String,Object>> data = new ArrayList<Map<String,Object>>();
		for (int i = 0; i < columnSize; i++) {
			ColumnClazz col = tableClazz.getColumns().get(i);
			//忽略掉ID
			if(col.isPK())continue;
			
			
			Map<String,Object> map = new HashMap<String, Object>();
			map.put("seq", i+1);
			map.put("name",col.getName());
			map.put("cnName", col.getCnName());
			
			map.put("isQuery", false);
			map.put("isTable", true);
			map.put("isEdit", true);
			if(col.getJavaType().equals("Long")&&(col.getColumnName().indexOf("Id")!=-1)){
				map.put("editType", EditType.DIALOG.getName());
				//map.put("editRule", "");
			}else if(col.getColumnName().equals("remark")){
				map.put("editType",EditType.TEXTAREA.getName());
			}else if(col.getJavaType().equals("Date")){
				map.put("editType",EditType.DATE.getName());
			}else{
				map.put("editType", EditType.TEXTINPUT.getName());
				//map.put("editRule", "");
			}
			
			map.put("validateType1","");
			map.put("validateRule1", "");
			
			map.put("validateType2","");
			map.put("validateRule2", "");
			
			//map.put("validateType3","");
			//map.put("validateRule3", "");
			
			data.add(map);
		}
		model.setData(data);
		table.setModel(model);
		
		
		//table.validate();
		//table.repaint();
		SwingUtilities.updateComponentTreeUI(table);
	}

	/*public void reloadColumnPanel() {
		// colPane.setPreferredSize(new Dimension(600 ,500));

		mainPanel.setPreferredSize(new Dimension(parentFrame
				.getMinMainBoardWidth(), 500));
		mainPanel.removeAll();
		mainPanel.repaint();

		String tableName = txtTable.getText();
		TableClazz tableClazz = new TableClazz(tableName);
		int columnSize = tableClazz.getColumns().size();

		Vector<Vector<String>> vrow = new Vector<Vector<String>>();

		for (int i = 1; i <= columnSize; i++) {
			Vector<String> temp = new Vector<String>();
			ColumnClazz col = tableClazz.getColumns().get(i - 1);
			temp.addElement(i + "");
			temp.addElement(col.getPropName());
			temp.addElement(col.getPropCnName());
			temp.addElement("1");
			temp.addElement("1");
			temp.addElement("true");
			temp.addElement("true");
			temp.addElement("true");

			vrow.add(temp);
		}

		// JTable friends = new JTable (vrow,vcol);
		// friends.setPreferredScrollableViewportSize(new Dimension(600,
		// 100));//设置表格的大小
		JTable jTable = new JTable(vrow, vcol);

		jTable.setAutoscrolls(true);
		jTable.setFocusable(false);
		jTable.setColumnSelectionAllowed(false);

		// jTable.setRowSelectionAllowed(false);
		jTable.setRowHeight(22);
		jTable.setAutoResizeMode(0);
		// friends.setRowHeight (30);//设置每行的高度为20
		// friends.setRowHeight (0, 20);//设置第1行的高度为15
		// friends.setRowMargin (5);//设置相邻两行单元格的距离
		// friends.setRowSelectionAllowed (true);//设置可否被选择.默认为false
		// friends.setSelectionBackground (Color.white);//设置所选择行的背景色
		// friends.setSelectionForeground (Color.red);//设置所选择行的前景色
		// friends.setGridColor (Color.black);//设置网格线的颜色
		// friends.selectAll ();//选择所有行
		// friends.setRowSelectionInterval (0,2);//设置初始的选择行,这里是1到3行都处于选择状态
		// friends.clearSelection ();//取消选择
		// friends.setDragEnabled (false);//不懂这个
		// friends.setShowGrid (false);//是否显示网格线
		// friends.setShowHorizontalLines (false);//是否显示水平的网格线
		// friends.setShowVerticalLines (true);//是否显示垂直的网格线
		// friends.setValueAt ("tt", 0, 0);//设置某个单元格的值,这个值是一个对象
		// friends.doLayout ();
		// friends.setBackground (Color.lightGray);

		
		// jTable.setModel(t);

		// this.mainPanel.add(jTable);
		jViewport.add(jTable);
		parentFrame.validate();

		// panel.repaint();
		// this.parentFrame.validate();

	}*/
	
	public PropEditor buildEditor(String typeStr,String param){
		PropEditor editor = null;
		
		EditType edittype= null;
		for(EditType type : EditType.values()){
			if(typeStr.equals(type.getName())){
				edittype = type;
				break;
			}
		}
		
		if(edittype==null){
			edittype = EditType.TEXTINPUT;
		}
		
		switch (edittype) {
			case SELECT:
			case DIALOG:
			case TEXTINPUT:
				editor = new PropEditor(edittype);
				break;
		default:
			break;
		}
		
		return editor;
		
	}
	
	public ValidateRule buildValidateRule(String typeStr,String ruleStr){
		
		ValidateRule rule= null;
		
		ValidateType validatetype = null;
		for(ValidateType type : ValidateType.values()){
			if(typeStr.equals(type.getName())){
				validatetype = type;
				break;
			}
		}
		if(validatetype==null)return null;
		
		switch (validatetype) {
		case REQUIRED://必输校验
			rule =  new ValidateRule(ValidateType.REQUIRED);
			return rule;
		case  LENGTH://长度校验
			rule = new ValidateRule(ValidateType.LENGTH);
			String[] sizes = ruleStr.split(",");
			if(sizes.length>1){
				rule.setMinSize(sizes[0]);
				rule.setMaxSize(sizes[1]);						
			}else{
				rule.setMaxSize(sizes[0]);
			}
			break;
		case INTEGER://整数校验
			rule = new ValidateRule(ValidateType.INTEGER);
			String[] ss = ruleStr.split(",");
			if(ss.length>1){
				rule.setMin(ss[0]);
				rule.setMax(ss[1]);						
			}else{
				rule.setMax(ss[0]);
			}
			break;
		case DECIMAL:
			String[] sss = ruleStr.split(",");
			rule = new ValidateRule(ValidateType.DECIMAL);
			if(sss.length>1){
				rule.setMin(sss[0]);
				rule.setMax(sss[1]);						
			}else{
				rule.setMax(sss[0]);
			}
			break;
		default:
			break;
		}
		
		return rule;
	}
	
	public void getTableValue(){
		List<Map<String,Object>> data = ((SingleTableModel)table.getModel()).getTableData();
		for(Map<String,Object> row :data){
			String columnName = (String)row.get("name");
			String columnCnName = (String) row.get("cnName");
			boolean isQuery = (Boolean)row.get("isQuery");
			boolean isTable = (Boolean)row.get("isTable");
			boolean isEdit = (Boolean)row.get("isEdit");
			
			String validateTypeName1 = (String) row.get("validateType1"); 
			String validateRule1 = (String) row.get("validateRule1");
			String validateTypeName2 = (String) row.get("validateType2"); 
			String validateRule2 = (String) row.get("validateRule2");
			//String validateTypeName3 = (String) row.get("validateType3"); 
			//String validateRule3 = (String) row.get("validateRule3");
			String editType=(String)row.get("editType");
			
			for(ColumnClazz col:this.tableClazz.getColumns()){
				if(col.getPropName().equals(columnName)){
					col.setPropCnName(columnCnName);
					col.setQueryCol(isQuery);
					col.setTableCol(isTable);
					col.setEditCol(isEdit);
					
					col.clearRule();//清空规则
					//校验规则
					ValidateRule rule = buildValidateRule(validateTypeName1, validateRule1); 
					if(rule!=null)col.addValidateRule(rule);
					ValidateRule rule2 = buildValidateRule(validateTypeName2, validateRule2); 
					if(rule2!=null)col.addValidateRule(rule2);
					
					if(editType!=null){
						PropEditor e = buildEditor(editType, null);
						col.setPropEditor(e);
					}
					
					//ValidateRule rule3 = buildValidateRule(validateTypeName3, validateRule3); 
					//if(rule3!=null)col.addValidateRule(rule3);
				}
			}
			
		}
	}
	
	@Override
	public void actionPerformed(ActionEvent e) {
		// btnGener.setEnabled(false);
		if(e.getActionCommand().equals("加载")){
		String moduleName = txtModule.getText();
		String tableName = txtTable.getText();

		reloadColumnPanel2();
		
		}else{//取值并生成
			/*Vector<Vector> data =  ((DefaultTableModel)table.getModel()).getDataVector();
			
			
			for(int i = 0;i<data.size();i++){
				Vector rowdata =data.get(i);
				
				String columnName = (String) rowdata.get(1);
				String columnCnName = (String) rowdata.get(2);
				String isQuery = (String)rowdata.get(3);
				String isTable = (String)rowdata.get(4);
				String isEdit = (String)rowdata.get(5);
				String isHidden = (String)rowdata.get(6);
				
				//校验规则
				String isRequired = (String)rowdata.get(7);
				String strSize = (String)rowdata.get(8);
				
				
				for(ColumnClazz col:this.tableClazz.getColumns()){
					if(col.getPropName().equals(columnName)){
						col.setPropCnName(columnCnName);
						col.setQueryCol(GenerUtil.getBool(isQuery));
						col.setTableCol(GenerUtil.getBool(isTable));
						col.setEditCol(GenerUtil.getBool(isEdit));
						col.setHiddenEditCol(GenerUtil.getBool(isHidden));
						
						col.clearRule();//清空规则
						//校验规则
						if(GenerUtil.getBool(isRequired)){
							ValidateRule required =  new ValidateRule(ValidateType.REQUIRED);
							col.addValidateRule(required);
						}
						if(!"".equals(strSize.trim())){
							String[] sizes = strSize.split(",");
							ValidateRule size = new ValidateRule(ValidateType.LENGTH);
							if(sizes.length>1){
								size.setMinSize(sizes[0]);
								size.setMaxSize(sizes[1]);						
							}else{
								size.setMaxSize(sizes[0]);
							}
							col.addValidateRule(size);
						}
						
						break;
					}
				}
			}
			doGenerAction();*/
			getTableValue();
			doGenerAction();
		}
	}
	
	public void doGenerAction(){
		try {
			String moduleName = txtModule.getText();
			String tableName = txtTable.getText();
			
			//1 生成
			if(this.tableClazz==null){
				this.tableClazz = new TableClazz(tableName);
			}
			SingleTableGenerator2 gener = new SingleTableGenerator2(moduleName);
			gener.generator(tableName,this.tableClazz);
			
			Runtime.getRuntime().exec("cmd.exe /c start "+ GeneratorProperties.getRequiredProperty("outRoot"));
		} catch (Exception ee) {
			ee.printStackTrace();
			// JOptionPane.showMessageDialog(parentFrame,
			// "生成代码报错："+ee.getMessage());
			// btnGener.setEnabled(true);
			return;
		}
	}
	
	public static void main(String[] args) {
		try {

			SingleTableGenerator2 gener = new SingleTableGenerator2("portal");
			//gener.generator("BM_CODE_NAME");

			// SingleTableGenerator2 gener = new
			// SingleTableGenerator2("portal");
			// gener.generatorTable("BM_CODE_TYPE");

			// Runtime.getRuntime().exec("cmd.exe /c start "+
			// GeneratorProperties.getRequiredProperty("outRoot"));
		} catch (Exception ee) {
			ee.printStackTrace();
			// JOptionPane.showMessageDialog(parentFrame,
			// "生成代码报错："+ee.getMessage());
			// btnGener.setEnabled(true);
			return;
		}
	}
	
	
	private class SingleTableModel extends AbstractTableModel {
		private Map<String,String> columnMap = new LinkedHashMap<String,String>();
		private List<Map<String,Object>> data = new ArrayList<Map<String,Object>>() ;
		
		public void setColumnMap(LinkedHashMap<String,String> map){
			columnMap.clear();
			columnMap.putAll(map);
		}
		
		public void setData(List<Map<String,Object>> adata){
			data.clear();
			data.addAll(adata);
		}
		
		public int getColumnCount() {
			return columnMap.size();
		}

		public int getRowCount() {
			return data.size();
		}

		public String getColumnName(int col) {
			int i=0;
			for(Entry<String, String> entry: columnMap.entrySet()){
				if(i==col)return entry.getValue();
				i++;
			}
			return "";
		}

		public Object getValueAt(int row, int col) {
			String key = getColumnKey(col);
			Object result = data.get(row).get(key);
			return result;
		}
		
		public String getColumnNameByKey(String key){
			return columnMap.get(key);
		}
		
		private String getColumnKey(int col){
			int i=0;
			for(Entry<String, String> entry: columnMap.entrySet()){
				if(i==col)return entry.getKey();
				i++;
			}
			return null;
		}

		/*
		 * JTable uses this method to determine the default renderer/ editor for
		 * each cell. If we didn't implement this method, then the last column
		 * would contain text ("true"/"false"), rather than a check box.
		 */
		public Class getColumnClass(int c) {
			// 实现了如果是boolean自动转成JCheckbox
			/*
			 * 需要自己的celleditor这么麻烦吧。jtable自动支持Jcheckbox，
			 * 只要覆盖tablemodel的getColumnClass返回一个boolean的class，
			 * jtable会自动画一个Jcheckbox给你， 你的value是true还是false直接读table里那个cell的值就可以
			 */
			//System.out.println("==============" + getValueAt(0, c).getClass());
			return getValueAt(0, c).getClass();
		}

		/*
		 * Don't need to implement this method unless your table's editable.
		 */
		public boolean isCellEditable(int row, int col) {
			// Note that the data/cell address is constant,
			// no matter where the cell appears onscreen.
			if(col>1)return true;
			return false;
		}

		/*
		 * Don't need to implement this method unless your table's data can
		 * change.
		 */
		public void setValueAt(Object value, int row, int col) {
			Map<String,Object> map = data.get(row);
			String key = this.getColumnKey(col);
			map.put(key, value);
		}
		
		
		public List<Map<String,Object>> getTableData(){
			return this.data;
		}
	}
}